package com.otaku.admin.security;

import com.alibaba.fastjson.JSON;
import com.otaku.admin.dao.entity.SelfUserDetails;
import com.otaku.admin.dao.entity.Token;
import com.otaku.admin.service.RedisTemplateService;
import com.otaku.admin.service.TokenService;
import com.otaku.admin.util.*;
import com.otaku.common.util.DateUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.stereotype.Component;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.UUID;

/**
 * 登陆成功返回给前端
 */
@Component
public class AjaxAuthenticationSuccessHandler implements AuthenticationSuccessHandler {

    private static final Logger LOGGER = LoggerFactory.getLogger(AjaxAuthenticationSuccessHandler.class);
    @Autowired
    private TokenService tokenService;
    @Autowired
    private RedisTemplateService redisTemplateService;
    @Override
    public void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {
        SelfUserDetails userDetails = (SelfUserDetails) authentication.getPrincipal();
        String accessToken = JwtTokenUtil.generateToken(userDetails, NumericTypeConstant.ACCESS_TOKEN_TIME_OUT * 1000L);//分钟
        String refreshToken = JwtTokenUtil.generateToken(userDetails, NumericTypeConstant.REFRESH_TOKEN_TIME_OUT * 1000L * 60L * 60 * 24);//小时
        Token token = new Token();
        token.setId(UUID.randomUUID().toString());
        token.setStatus(NumericTypeConstant.TOKEN_STATUS_SUCCESS);
        token.setUserId(userDetails.getId());
        token.setAccessToken(accessToken);
        token.setRefreshToken(refreshToken);
        token.setRefreshTimeOut(DateUtils.addDays(NumericTypeConstant.REFRESH_TOKEN_TIME_OUT));
        /**
         * 将该用户所有token失效化
         */
        LOGGER.info("用户{}登录成功，生成token：{}",userDetails.getUsername(),accessToken);
        tokenService.updateStatusByUserId(userDetails.getId(),NumericTypeConstant.TOKEN_STATUS_INVALID);
        /**
         * 保存当前用户有效token
         */
        tokenService.saveToken(token);
        /**
         * 将该用户redis缓存更新
         */
        boolean set = redisTemplateService.set(StringTypeConstant.getRedisTokenTitles(userDetails.getUsername()), NumericTypeConstant.REDIS_TOKEN_TIME_OUT * 60L, accessToken);
        LOGGER.info("redis缓存结果：{}",set);
        httpServletResponse.setHeader("Content-type", "text/html;charset=UTF-8");
        httpServletResponse.getWriter().write(JSON.toJSONString(ResultVO.result(ResultEnum.USER_LOGIN_SUCCESS, accessToken, true)));
    }
}
